package com.magic.cd.core;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Map;

import com.magic.cd.util.Const;
import com.magic.cd.util.MiniCatUtils;

/**
 * MyCatClient
 * */
@SuppressWarnings({"static-access","unused"})
public class MiniCatClient {
	private String host;
	private int port;
	private String dbs;
	
	private Socket socket;
	private InputStream in;
	private OutputStream out;
	
	private boolean isLogin = false;
	private Map<String,Object> serverStatus;
	
	/**
	 * @param	host   主机地址用:分割，如：localhost:3306:magic_dev
	 * */
	public MiniCatClient(String host){
		if(host==null||host.length()<8){
			throw new RuntimeException("地址错误！");
		}
		String[] hosts = host.split(":");
		this.host = hosts[0];
		this.port = Integer.valueOf(hosts[1]);
		this.dbs = hosts[2];
	}
	
	/**
	 * 连接并登陆客户端
	 * @param	host   主机地址用:分割，如：localhost:3306:magic_dev
	 * @throws Exception 
	 * */
	public void login(String name,String pwd){
		isLogin = true;
		if(this.socket==null) socket = new MySocket(this.host, this.port).connect();
		
		try {
		 	Thread.currentThread().sleep(5);

			socket.setTcpNoDelay(true);
			socket.setKeepAlive(true);
			
			in = socket.getInputStream();
			out = socket.getOutputStream();
			
			this.readShakePacket();
			this.doAuthority(name,pwd,(String)serverStatus.get("seed"));
			this.checkLogin();
			
		} catch (Exception e) {
			throw new RuntimeException("登陆失败！");
		}
	}
	
	/**
	 * 发送查询SQL并返回结果
	 * @param	sql		符合条件的SQL
	 * @return  String
	 * @throws
	 * */
	public String query(String sql) throws Exception{
		if(!isLogin) throw new RuntimeException("请先调用登录方法！");
			
		byte[] query_head = new byte[5];
		query_head[0] = (byte)(sql.length()+1+1);
		query_head[4] = (byte)(Const.COM_QUERY);
		
		byte[] query_body = MiniCatUtils.getBytes(sql);
		byte[] query_byte = MiniCatUtils.append(query_head, query_body);
		
		MiniCatPacket query = new MiniCatPacket(query_byte);
		out.write(query.getBytePacket(),0,query.getMaxLength());
		out.flush();
		Thread.currentThread().sleep(10);
		//-----------解析查询结果----------------
		byte[] origin_qw = new byte[in.available()];
		int status_qw = in.read(origin_qw);
		
		//这里不做结果的解析，要解析请参考相关MySQL协议
		return new String(origin_qw,"UTF-8");
	}
	
	/**
	 * 解析初始握手包
	 * */
	private void readShakePacket() throws Exception{
		if(this.serverStatus!=null) return;
		
		StringBuffer sb = new StringBuffer();
		byte[] origin = new byte[in.available()];
		
		int status = in.read(origin);
		MiniCatPacket pkg = MiniCatUtils.parsePacket(origin);
		serverStatus = MiniCatUtils.parseShakePkg(pkg);
	}
	
	/**
	 * 发送授权认证包
	 * */
	private void doAuthority(String name,String pwd,String seed) throws Exception{
		MiniCatPacket send = MiniCatUtils.loginPkg(name, pwd, this.dbs, seed);

		//报文头
		byte[] head = new byte[4];
		head[0]=90;
		head[3]=1;
		
		byte[] newByte = MiniCatUtils.append(head, send.getBytePacket());
		out.write(newByte,0,94);
		out.flush();
		Thread.currentThread().sleep(50);
	}
	
	/**
	 * 检查登录信息
	 * */
	private void checkLogin() throws Exception{

		byte[] origin_pw = new byte[in.available()];
		int status_pw = in.read(origin_pw);
		
		//检查第一位是否为0xFF
		byte login_status = MiniCatUtils.read(origin_pw, 4, 1)[0];
		
		String log = new String(origin_pw,"UTF-8");
		
		if(login_status==0){
			System.out.println("登录成功！");
			System.out.println("登陆信息："+log);
		}else{
			System.err.println("登陆失败！");
			System.err.println("登陆信息："+log);
			throw new RuntimeException("登陆失败！");
		}
	}
	
	/**
	 * 获取服务器信息，请在登陆后使用
	 * */
	public Map<String,Object> getServerStatus() throws Exception{
		if(this.isLogin&&this.serverStatus==null) this.readShakePacket();
		return this.serverStatus;
	}
}
